package com.guapi.service;

import com.guapi.dao.UserMapper;
import com.guapi.entity.LoginTicket;
import com.guapi.entity.User;
import com.guapi.util.MailClient;
import com.guapi.util.MallConstant;
import com.guapi.util.MallUtil;
import com.guapi.util.RedisKeyUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

@Service
public class UserService implements MallConstant {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private TemplateEngine templateEngine;

    @Autowired
    private MailClient mailClient;

    @Value("${second-mall.path.header}")
    private String header;

    @Value("${second-mall.path.domain}")
    private String domain;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    public User findUserById(int userId) {
        return userMapper.selectByUserId(userId);
    }

    /**
     * 注册用户，给用户发送验证码
     *
     * @param user
     * @return
     */
    public Map<String, Object> register(User user) {
        HashMap<String, Object> map = new HashMap<>();
        if (user == null) {
            throw new IllegalArgumentException("用户不能为空");
        }
        if (StringUtils.isBlank(user.getUserName())) {
            map.put("usernameMsg", "用户名不能为空");
            return map;
        }
        if (StringUtils.isBlank(user.getPassword())) {
            map.put("passwordMsg", "密码不能为空");
            return map;
        }

        if (StringUtils.isBlank(user.getEmail())) {
            map.put("emailMsg", "邮箱不能为空");
            return map;
        }
        //验证账号
        User judgeUser = userMapper.selectByUserName(user.getUserName());
        if (judgeUser != null) {
            map.put("usernameMsg", "该用户已经存在");
            return map;
        }
        //注册用户
        user.setHeaderUrl(String.format(domain+contextPath+"/"+header + "%d.png", new Random().nextInt(12)));
        // 打算使用存在本地的头像，在resources路径下
        //user.setAddress();这个还不知道从哪设置，或许从注册页面？还是个人信息修改页面？
        //设置用户密码的‘盐’
        user.setSalt(MallUtil.generateUUID().substring(0, 5));
        //对用户的密码进行加盐处理
        user.setPassword(MallUtil.md5(user.getPassword() + user.getSalt()));
        user.setActivationCode(MallUtil.generateUUID());
        user.setCreateTime(new Date());
        user.setStatus(1);
        user.setType(0);


        userMapper.insertUser(user);

        //给用户发送注册邮件
        Context context = new Context();

        //设计验证路径...
        String url = domain + contextPath + "/activation/" + user.getId() + "/" + user.getActivationCode();
        context.setVariable("email", user.getEmail());
        context.setVariable("url", url);
        context.setVariable("username", user.getUserName());

        //验证注册页面的路径
        String content = templateEngine.process("/mail/activation", context);

        mailClient.sendMail(user.getEmail(), "激活账号", content);
        return map;
    }

    public int activation(int userId, String code) {
        User user = userMapper.selectByUserId(userId);
        if (user.getStatus() == USER_ACTIVATION_SUCCESS) {
            return USER_ACTIVATION_REPEAT;
        } else if (user.getActivationCode().equals(code)) {
            userMapper.updateStatus(userId, USER_ACTIVATION_SUCCESS);
            return USER_ACTIVATION_SUCCESS;
        } else {
            return USER_ACTIVATION_FAILURE;
        }
    }

    public Map<String, Object> login(String username, String password, int expire) {
        HashMap<String, Object> map = new HashMap<>();
        //处理空值
        if (StringUtils.isBlank(username)) {
            map.put("loginUsernameMsg", "用户名不能为空");
            return map;
        }
        if (StringUtils.isBlank(password)) {
            map.put("loginPasswordMsg", "密码不能为空");
            return map;
        }
        //验证账号
        User user = userMapper.selectByUserName(username);
        if (user == null) {
            map.put("loginUsernameMsg", "该用户不存在");
            return map;
        } else if (user.getStatus() != 0) {
            map.put("loginUsernameMsg", "该用户未激活");
            return map;
        }

        //验证密码
        password = MallUtil.md5(password + user.getSalt());

        if (!password.equals(user.getPassword())) {
            map.put("loginPasswordMsg", "密码不正确");
            return map;
        }

        LoginTicket loginTicket = new LoginTicket();
        loginTicket.setUserId(user.getId());
        loginTicket.setTicket(MallUtil.generateUUID());
        loginTicket.setStatus(1);
        loginTicket.setExpired(new Date(System.currentTimeMillis() + expire * 1000));

        //登录凭证存入redisKey
        String loginTicketKey = RedisKeyUtil.getLoginTicketKey(loginTicket.getTicket());
        //redisTemplate.expire(loginTicketKey,loginTicket.getExpired().getTime(), TimeUnit.SECONDS);
        //登录信息存入redis，redis会将其序列化成json
        redisTemplate.opsForValue().set(loginTicketKey, loginTicket);


        map.put("ticket", loginTicket.getTicket());
        return map;

    }

    public LoginTicket findLoginTicket(String ticket) {
        String redisKey = RedisKeyUtil.getLoginTicketKey(ticket);
        return (LoginTicket) redisTemplate.opsForValue().get(redisKey);
    }

    public void logout(String ticket){
        String redisKey = RedisKeyUtil.getLoginTicketKey(ticket);
        LoginTicket loginTicket = (LoginTicket) redisTemplate.opsForValue().get(redisKey);
        loginTicket.setStatus(0);
        redisTemplate.opsForValue().set(redisKey,loginTicket);
    }

    public int updateHeader(int id, String headerUrl) {
        int i = userMapper.updateHeader(id, headerUrl);
        return i;

    }

    public Map<String,Object> sendModifyPasswordMail(User user,String password,String email){

        HashMap<String, Object> map = new HashMap<>();
        if (password == null) {
            map.put("passwordMsg","请填入您的新密码");
            return map;
        }
        if (email == null) {
            map.put("emailMsg","请填入您的密保邮箱");
            return map;
        }
        if (user==null){
            map.put("userMsg","该邮箱注册的用户不存在");
            return map;
        }
        if (user.getEmail()!=email){
            map.put("emailMsg","该邮箱不是您的密保邮箱");
        }
        Context context = new Context();

        //设置验证路径


        String url =domain+contextPath+"/user/modify/"+user.getUserName()+"/"+MallUtil.md5(password+user.getSalt());

        context.setVariable("url", url);
        context.setVariable("username", user.getUserName());

        String page = templateEngine.process("/mail/forget", context);

        mailClient.sendMail(user.getEmail(),"修改用户密码",page);
        return map;
    }


    public User findUserByName(String username) {
        return userMapper.selectByUserName(username);
    }

    public int updatePassword(User user,String password) {
        return userMapper.updatePassword(user.getId(),password);
    }

    public User findUserByEmail(String userEmail) {
        return userMapper.selectByUserEmail(userEmail);
    }

    public int updateAddress(int id, String address){
        return userMapper.updateAddress(id, address);
    }
}
